Skip to main content

TypeScript Setup

Resource: WebDevSimplified - TypeScript Setup

I. What/Why TypeScript

TypeScript is basically just JavaScript with types added on top of it.

Despite misconceptions, TypeScript doesn’t slow you down but speeds up development by providing:

  • Auto-complete everywhere, even in abstracted/separate functions
  • Bug detection: flags nonexistent properties at compile time → allowing you to see errors that are invisible in JavaScript.

1. The Problem with Plain JavaScript

a. Auto-Complete Works... Until It Doesn't

Consider this straightforward JavaScript example:

const button = document.createElement("button");

button.addEventListener("click", handleClick);

function handleClick(e) {
console.log(e.anyTarget); // typo at intended "target"
}

VS Code is smart enough to infer types in simple, inline scenarios. For example, when you write document.createElement("button") directly, VS Code infers the type is HTMLButtonElement and gives you solid auto-complete.

However, the moment you extract logic into a separate function (like handleClick above), that type inference breaks down:

  • e has no type information hovering over it shows it could be anything
  • Auto-complete on e. returns nothing
  • A typo like e.anyTarget produces no error at compile time

b.Silent Bugs at Runtime

In JavaScript, accessing a property that doesn't exist on an object doesn't throw an error, it simply returns undefined:

// No error thrown — just logs "undefined" to the console
function handleClick(e) {
console.log(e.anyTarget); // undefined, not an error
}

This means your bug goes completely undetected, even though you clearly intended to write e.target.

c. How TypeScript Solves This

The Same Code in TypeScript (.ts)

const button = document.createElement("button");

button.addEventListener("click", handleClick);

function handleClick(e: MouseEvent) {
console.log(e.anyTarget); // TypeScript Error: Property 'anyTarget' does not exist on type 'MouseEvent'
}

By adding type MouseEvent as the type annotation for e you immediately get:

  1. An error flagging anyTarget as invalid
  2. Full auto-complete on e., showing valid properties like target, currentTarget, etc.
const button = document.createElement("button");

button.addEventListener("click", handleClick);

function handleClick(e: MouseEvent) {
console.log(e.target); // Correct — full auto-complete guided this

II. TypeScript Project Setup

Your browser can’t actually run TypeScript, only JavaScript, so TypeScript compiles all your code down to JavaScript.

a. Manual Setup

# 1. Initialize project
npm init -y

# 2. Install TypeScript
npm install -D typescript

# 3. Create tsconfig.json
npx tsc --init

# 4. Compile (based on tsconfig.json -- creating js files)
npx tsc

# 5. Compile and block output on errors
npx tsc --noEmitOnError

tsconfig.json

1. Compiled JS files location

Common pattern: src/ for source code .ts, dist/ for output .js

  • rootDir: source folder (e.g., src/)
  • outDir: compiled output folder (e.g., dist/)
2. Prevent Compiling When Error

By default, TypeScript still outputs JS even with errors

  • Use npx tsc --noEmitOnError
// or set up in tsconfig.json
```json
{
"compilerOptions": {
"noEmitOnError": true
}
}

b. Using a Bundler